In [1]:
import cv2
import numpy as np
import matplotlib.pyplot as plt
from skimage.metrics import structural_similarity as ssim
from skimage.metrics import peak_signal_noise_ratio as psnr
In [23]:
img1 = cv2.imread('color.jpg')
img1_rgb = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
img2 = cv2.imread('bright.jpg')
img2_rgb = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
img3 = cv2.imread('gd.jpg')
img3_rgb = cv2.cvtColor(img3, cv2.COLOR_BGR2RGB)

plt.figure(figsize=(12, 6))
plt.subplot(1, 3, 1)
plt.imshow(img1_rgb)
plt.axis('off')

plt.subplot(1, 3, 2)
plt.imshow(img2_rgb)
plt.axis('off')
plt.tight_layout()

plt.subplot(1, 3, 3)
plt.imshow(img3_rgb)
plt.axis('off')
plt.tight_layout()

plt.show()
No description has been provided for this image
In [3]:
kernel1 = np.array([
    [-1, -1, -1], 
    [-1, 9, -1], 
    [-1, -1, -1]
    ])

kernel2 = np.array([
    [0, -1, 0], 
    [-1, 5, -1], 
    [0, -1, 0]
    ])

kernel3 = np.ones((5, 5), np.float32) / 25

kernel4 = np.array([
    [1, 1, 1], 
    [1, 1, 1], 
    [1, 1, 1]
    ]) / 9

kernel5 = np.array([
    [1, 4, 6, 4, 1], 
    [4, 16, 24, 16, 4], 
    [6, 24, 36, 24, 6], 
    [4, 16, 24, 16, 4], 
    [1, 4, 6, 4, 1]]) / 256

kernels = [kernel1, kernel2, kernel3, kernel4, kernel5]
kernel_names = ['Sharpen 1', 'Sharpen 2', 'Blur 1', 'Blur 2', 'Gaussian Blur']
In [25]:
plt.figure(figsize=(15, 12))
for i, (kernel, name) in enumerate(zip(kernels, kernel_names)):
    result1 = cv2.filter2D(img1_rgb, -1, kernel)
    result2 = cv2.filter2D(img2_rgb, -1, kernel)
    result3 = cv2.filter2D(img3_rgb, -1, kernel)
    
    plt.subplot(5, 3, 3*i+1)
    plt.imshow(result1)
    plt.title(name)
    plt.axis('off')
    
    plt.subplot(5, 3, 3*i+2)
    plt.imshow(result2)
    plt.title(name)
    plt.axis('off')

    plt.subplot(5, 3, 3*i+3)
    plt.imshow(result3)
    plt.title(name)
    plt.axis('off')

plt.tight_layout()
plt.show()
No description has been provided for this image
In [30]:
noise1 = np.random.normal(0, 5, img1_rgb.shape).astype(np.uint8)
noisy1 = cv2.add(img1_rgb, noise1)

noise2 = np.random.normal(0, 5, img2_rgb.shape).astype(np.uint8)
noisy2 = cv2.add(img2_rgb, noise2)

noise3 = np.random.normal(0, 5, img3_rgb.shape).astype(np.uint8)
noisy3 = cv2.add(img3_rgb, noise3)


plt.figure(figsize=(12, 6))
plt.subplot(1, 3, 1)
plt.imshow(noisy1)
plt.axis('off')

plt.subplot(1, 3, 2)
plt.imshow(noisy2)
plt.axis('off')
plt.tight_layout()

plt.subplot(1, 3, 3)
plt.imshow(noisy3)
plt.axis('off')
plt.tight_layout()

plt.show()
No description has been provided for this image
In [36]:
def apply_filters(img):
    results = {}
    
    # Blur
    results['Mean'] = cv2.blur(img, (5, 5))
    results['Gaussian'] = cv2.GaussianBlur(img, (5, 5), 0)
    results['Median'] = cv2.medianBlur(img, 5)
    results['Bilateral'] = cv2.bilateralFilter(img, 9, 75, 75)
    
    # Sobel
    gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
    sobel_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
    sobel_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
    sobel_xy = cv2.Sobel(gray, cv2.CV_64F, 1, 1, ksize=3)
    sobel_combined = np.sqrt(sobel_x**2 + sobel_y**2)
    
    results['Sobel X'] = cv2.cvtColor(np.uint8(np.abs(sobel_x)), cv2.COLOR_GRAY2RGB)
    results['Sobel Y'] = cv2.cvtColor(np.uint8(np.abs(sobel_y)), cv2.COLOR_GRAY2RGB)
    results['Sobel XY'] = cv2.cvtColor(np.uint8(np.abs(sobel_xy)), cv2.COLOR_GRAY2RGB)
    results['Sobel Combined'] = cv2.cvtColor(np.uint8(sobel_combined), cv2.COLOR_GRAY2RGB)
    
    # Laplacian
    laplacian = cv2.Laplacian(gray, cv2.CV_64F)
    results['Laplacian'] = cv2.cvtColor(np.uint8(np.abs(laplacian)), cv2.COLOR_GRAY2RGB)
    
    # Non-Local Means
    nlm = cv2.fastNlMeansDenoisingColored(img, None, 10, 10, 7, 21)
    results['Non-Local Means'] = nlm

    # Box Filter
    results['Box Filter'] = cv2.boxFilter(img, -1, (9, 9))

    # Canny
    canny = cv2.Canny(gray, 100, 200)
    results['Canny'] = cv2.cvtColor(canny, cv2.COLOR_GRAY2RGB)
    
    # Errosion
    kernel = np.ones((5, 5), np.uint8)
    results['Erosion'] = cv2.erode(img, kernel, iterations=1)

    return results
In [37]:
filtered1 = apply_filters(noisy1)
filtered2 = apply_filters(noisy2)
filtered3 = apply_filters(noisy3)

filter_names = list(filtered1.keys())
plt.figure(figsize=(20, 30))

for i, name in enumerate(filter_names):
    plt.subplot(len(filter_names), 3, 3*i+1)
    plt.imshow(filtered1[name])
    plt.title(name)
    plt.axis('off')
    
    plt.subplot(len(filter_names), 3, 3*i+2)
    plt.imshow(filtered2[name])
    plt.title(name)
    plt.axis('off')

    plt.subplot(len(filter_names), 3, 3*i+3)
    plt.imshow(filtered3[name])
    plt.title(name)
    plt.axis('off')

plt.tight_layout()
plt.show()
No description has been provided for this image
In [44]:
def calculate_metrics(original, processed):
    psnr_val = psnr(original, processed)
    ssim_val = ssim(original, processed, multichannel=True, channel_axis=2)
    return psnr_val, ssim_val

results1 = {}
results2 = {}
results3 = {}

for name in filter_names:
    psnr1, ssim1 = calculate_metrics(img1_rgb, filtered1[name])
    psnr2, ssim2 = calculate_metrics(img2_rgb, filtered2[name])
    psnr3, ssim3 = calculate_metrics(img3_rgb, filtered3[name])
    
    results1[name] = {'PSNR': psnr1, 'SSIM': ssim1}
    results2[name] = {'PSNR': psnr2, 'SSIM': ssim2}
    results3[name] = {'PSNR': psnr3, 'SSIM': ssim3}
In [50]:
import pandas as pd
from IPython.display import display
import warnings
warnings.filterwarnings("ignore")

data = []
for name in filter_names:
    row = [
        results1[name]['PSNR'], results1[name]['SSIM'],
        results2[name]['PSNR'], results2[name]['SSIM'],
        results3[name]['PSNR'], results3[name]['SSIM']
    ]
    data.append(row)

df = pd.DataFrame(data, index=filter_names, 
                  columns=['Image 1 PSNR', 'Image 1 SSIM', 
                           'Image 2 PSNR', 'Image 2 SSIM',
                           'Image 3 PSNR', 'Image 3 SSIM'])

def psnr_color(val):
    norm_val = min(max(val / 50, 0), 1)
    return f'background-color: rgba({255*(1-norm_val)}, {0}, {255*norm_val}, 0.7)'

def ssim_color(val):
    norm_val = min(max((val + 1) / 2, 0), 1) 
    return f'background-color: rgba({255*(1-norm_val)}, {0}, {255*norm_val}, 0.7)'

styled_df = df.style.format("{:.2f}")

for col in [0, 2, 4]:  
    styled_df = styled_df.applymap(psnr_color, subset=df.columns[col])

for col in [1, 3, 5]:
    styled_df = styled_df.applymap(ssim_color, subset=df.columns[col])

display(styled_df)
  Image 1 PSNR Image 1 SSIM Image 2 PSNR Image 2 SSIM Image 3 PSNR Image 3 SSIM
Mean 10.47 0.32 15.91 0.67 12.05 0.42
Gaussian 10.34 0.31 15.95 0.65 11.94 0.42
Median 9.96 0.19 14.83 0.44 11.27 0.31
Bilateral 7.52 0.17 13.90 0.58 9.39 0.33
Sobel X 7.57 -0.00 3.55 -0.02 5.10 -0.01
Sobel Y 7.59 -0.00 3.55 -0.02 5.14 -0.00
Sobel XY 7.67 -0.00 3.02 -0.01 5.05 -0.00
Sobel Combined 7.40 0.00 4.22 -0.02 5.23 0.00
Laplacian 7.55 -0.00 3.75 -0.03 5.11 -0.02
Non-Local Means 7.39 0.12 14.12 0.56 9.19 0.32
Box Filter 10.54 0.32 15.65 0.65 12.11 0.42
Canny 4.86 -0.00 2.40 -0.01 3.58 -0.00
Erosion 19.68 0.53 17.05 0.71 17.76 0.51
In [53]:
plt.figure(figsize=(16, 8))

plt.subplot(3, 4, 1)
plt.imshow(img1_rgb)
plt.title('Original')
plt.axis('off')

plt.subplot(3, 4, 2)
plt.imshow(noisy1)
plt.title('Noisy')
plt.axis('off')

plt.subplot(3, 4, 3)
plt.imshow(filtered1["Erosion"])
plt.title(f'Best: Erosion')
plt.axis('off')

plt.subplot(3, 4, 4)
plt.text(0.1, 0.7, f'PSNR: {results1["Erosion"]["PSNR"]:.2f}', fontsize=12)
plt.text(0.1, 0.5, f'SSIM: {results1["Erosion"]["SSIM"]:.4f}', fontsize=12)
plt.text(0.1, 0.3, 'Filter: Erosion', fontsize=12)
plt.title('Quality Metrics')
plt.axis('off')

plt.subplot(3, 4, 5)
plt.imshow(img2_rgb)
plt.title('Original')
plt.axis('off')

plt.subplot(3, 4, 6)
plt.imshow(noisy2)
plt.title('Noisy')
plt.axis('off')

plt.subplot(3, 4, 7)
plt.imshow(filtered2["Erosion"])
plt.title('Best: Erosion')
plt.axis('off')

plt.subplot(3, 4, 8)
plt.text(0.1, 0.7, f'PSNR: {results2["Erosion"]["PSNR"]:.2f}', fontsize=12)
plt.text(0.1, 0.5, f'SSIM: {results2["Erosion"]["SSIM"]:.4f}', fontsize=12)
plt.text(0.1, 0.3, 'Filter: Erosion', fontsize=12)
plt.title('Quality Metrics')
plt.axis('off')

plt.subplot(3, 4, 9)
plt.imshow(img3_rgb)
plt.title('Original')
plt.axis('off')

plt.subplot(3, 4, 10)
plt.imshow(noisy3)
plt.title('Noisy')
plt.axis('off')

plt.subplot(3, 4, 11)
plt.imshow(filtered3["Erosion"])
plt.title('Best: Erosion')
plt.axis('off')
plt.subplot(3, 4, 12)
plt.text(0.1, 0.7, f'PSNR: {results3["Erosion"]["PSNR"]:.2f}', fontsize=12)
plt.text(0.1, 0.5, f'SSIM: {results3["Erosion"]["SSIM"]:.4f}', fontsize=12)
plt.text(0.1, 0.3, 'Filter: Erosion', fontsize=12)
plt.title('Quality Metrics')
plt.axis('off')

plt.tight_layout()
plt.show()
No description has been provided for this image

overall erosion was the best for the noisy image recovery.

noise reduction filters like mean, gaussian, box filters had poor to fair performance.

the edge detection techniques performed the worse due to them only detecting the edges and loosing all other data

image base observations were that overall image 2 with the bird was the best followed by image 3 and then image 1.